package com.atguigu.gulimall.order.config;

import feign.RequestInterceptor;
import feign.RequestTemplate;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;

/**‘
 * 分布式session将用户的session信息保存在redis中
 * 但是想要获取到session还需要请求中携带用户的cookie
 *
 * feign远程调用时相重新创建了一个httpRequest
 * 如果被调用的服务需要获取用户信息才能查询出用户相关的数据
 * 则需要携带cookie / token 等可以提供用户信息的数据
 *
 * 可以直接将用户id当参数，也可以同步cookie信息
 *
 * 采用异步编排模式，feign会丢失请求上下文 RequestContextHolder.getRequestAttributes()获取不到数据
 * 解决方案，在异步编排远程请求任务时，先获取处理请求的线程的上下文，
 *      然后将其设置到异步任务RequestContextHolder.setRequestAttributes()的上下文
 */
@Configuration
public class FeignConfig {

    @Bean
    public RequestInterceptor requestInterceptor(){
        return new RequestInterceptor(){

            @Override
            public void apply(RequestTemplate template) {
//                那当当前请求的数据
                /**
                 * RequestContextHolder采用ThreadLocal保存request上下文 attributes(request response session)
                 * 但是异步编排业务会导致这个地方无法拿到上下文attributes
                 */
                ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();

                HttpServletRequest request = attributes.getRequest();

//              同步请求头数据
                template.header("Cookie",request.getHeader("Cookie"));
                System.out.println("feign远程之前先进行调用apply");
            }
        };
    }
}
